# # # # import numpy as np 
# # # # import matplotlib.pyplot as plt

# # # # # # Logistic映射方程
# # # # # def logistic_map(r, x0):
# # # # #     x = np.zeros(200)
# # # # #     x[0] = x0
# # # # #     for i in range(199):
# # # # #         x[i+1] = r*x[i]*(1-x[i])
# # # # #     return x

# # # # # # 绘制轨迹图    
# # # # # def plot_logistic_map(r): 
# # # # #     x = logistic_map(r, 0.52)
# # # # #     plt.figure()
# # # # #     plt.plot(x, 'r-')
# # # # #     plt.xlabel('n')
# # # # #     plt.ylabel('x')
# # # # #     plt.title('r = %.2f' % r)
# # # # #     plt.show()

# # # # # # # 三个不同r值下的Logistic映射轨迹  
# # # # # plot_logistic_map(3.2)     # 准周期
# # # # # plot_logistic_map(3.5699)   # 周期-混沌过渡 
# # # # # plot_logistic_map(3.9)      # 混沌

# # # # # def lyapunov_exponent(x0, r, ds0 = 1e-3):
# # # # #     # trajectory 1
# # # # #     x = logistic_map(r, x0)
# # # # #     # trajectory 2
# # # # #     x2 = logistic_map(r, x0 + ds0)
# # # # #     # difference
# # # # #     ds = np.abs(x2 - x)

# # # # #     print("shape of ds: ", ds.shape)
# # # # #     # Lyapunov exponent
# # # # #     lnr = np.log(ds)
# # # # #     slope, intercept = np.polyfit(list(range(len(lnr))), lnr, deg=1)
# # # # #     print("slope: ", slope)
# # # # #     # # plot lnr
# # # # #     # plt.figure()
# # # # #     # plt.plot(lnr, 'r-')
# # # # #     # plt.xlabel('n')
# # # # #     # plt.ylabel('lnr')
# # # # #     # plt.title("lyapunov exponent: " + str(slope))
# # # # #     # plt.show()

# # # # #     # do FFT on ds
# # # # #     fft = np.fft.fft(ds)
# # # # #     print("shape of fft: ", fft.shape)
# # # # #     print(fft)
# # # # #     fft = fft / fft.max()
# # # # #     # # plot fft
# # # # #     # plt.figure()
# # # # #     # plt.plot(np.abs(fft), 'r-')
# # # # #     # plt.xlabel('n')
# # # # #     # plt.ylabel('fft')
# # # # #     # plt.title("fft")
# # # # #     # plt.show()

# # # # #     # show two plots plus plot of x side by side
# # # # #     fig, axs = plt.subplots(1, 3, figsize=(12, 4))
# # # # #     axs[0].plot(x, 'r-')
# # # # #     axs[0].set_xlabel('n')
# # # # #     axs[0].set_ylabel('x')
# # # # #     axs[0].set_title('r = %.2f' % r)
# # # # #     axs[1].plot(lnr, 'r-')
# # # # #     axs[1].set_xlabel('n')
# # # # #     axs[1].set_ylabel('lnr')    
# # # # #     axs[1].set_title("lyapunov exponent: " + str(slope))
# # # # #     axs[2].plot(np.abs(fft[1:-1]), 'r-')
# # # # #     axs[2].set_xlabel('n')
# # # # #     axs[2].set_ylabel('fft')
# # # # #     axs[2].set_title("fft")
# # # # #     # set y limit 0-1
# # # # #     axs[2].set_ylim(0, 1)
# # # # #     plt.show()
    

# # # # # lyapunov_exponent(x0=0.5, r=3.2)
# # # # # lyapunov_exponent(x0=0.5, r=3.5699)
# # # # # lyapunov_exponent(x0=0.5, r=3.9)
    

# # # # # # 创建图形和3D坐标系
# # # # # fig = plt.figure(figsize=(10, 8))
# # # # # ax = fig.add_subplot(111, projection='3d')

# # # # # # 设置坐标轴范围
# # # # # limit = 10
# # # # # ax.set_xlim(-limit, limit)
# # # # # ax.set_ylim(-limit, limit)
# # # # # ax.set_zlim(-limit, limit)

# # # # # # 绘制坐标轴
# # # # # ax.quiver(0, 0, 0, limit, 0, 0, color='r', arrow_length_ratio=0.1)
# # # # # ax.quiver(0, 0, 0, 0, limit, 0, color='g', arrow_length_ratio=0.1)
# # # # # ax.quiver(0, 0, 0, 0, 0, limit, color='b', arrow_length_ratio=0.1)

# # # # # # 在坐标轴末端添加标签
# # # # # ax.text(limit+1, 0, 0, "X", color='red', fontsize=14)
# # # # # ax.text(0, limit+1, 0, "Y", color='green', fontsize=14)
# # # # # ax.text(0, 0, limit+1, "Z", color='blue', fontsize=14)

# # # # # # 添加坐标轴标签
# # # # # ax.set_xlabel('X')
# # # # # ax.set_ylabel('Y')
# # # # # ax.set_zlabel('Z')

# # # # # # 创建两个相互垂直且经过Z轴的平面
# # # # # z = np.linspace(-limit, limit, 100)
# # # # # xy = np.linspace(-limit, limit, 100)
# # # # # Z, XY = np.meshgrid(z, xy)

# # # # # # 第一个平面 (y = x)
# # # # # X1 = XY
# # # # # Y1 = XY

# # # # # # 第二个平面 (y = -x)
# # # # # X2 = XY
# # # # # Y2 = -XY

# # # # # # 绘制平面
# # # # # ax.plot_surface(X1, Y1, Z, alpha=0.3, color='cyan')
# # # # # ax.plot_surface(X2, Y2, Z, alpha=0.3, color='magenta')

# # # # # # 添加H1到H4的标注
# # # # # label_pos = 7  # 标签位置
# # # # # ax.text(label_pos, 0, label_pos, "H1", fontsize=16, color='black')
# # # # # ax.text(0, label_pos, label_pos, "H2", fontsize=16, color='black')
# # # # # ax.text(-label_pos, 0, label_pos, "H3", fontsize=16, color='black')
# # # # # ax.text(0, -label_pos, label_pos, "H4", fontsize=16, color='black')


# # # # # # 设置视角
# # # # # ax.view_init(elev=20, azim=45)

# # # # # # 显示图形
# # # # # plt.show()


# # # # from scipy.stats import qmc

# # # # # def sobol_sequence(size, dim, range_min=-1, range_max=1, epsilon=1e-6):
# # # # #     # 创建Sobol采样器
# # # # #     sampler = qmc.Sobol(d=dim, scramble=True)
    
# # # # #     # 生成比需要的多一些的样本点，以便替换接近零的向量
# # # # #     extra_samples = int(size * 0.1)  # 额外10%的样本
# # # # #     total_samples = size + extra_samples
    
# # # # #     # 生成[0, 1)范围内的样本
# # # # #     sample = sampler.random(n=total_samples)
    
# # # # #     # 将样本从[0, 1)映射到[range_min, range_max]
# # # # #     sample_scaled = qmc.scale(sample, l_bounds=[range_min]*dim, u_bounds=[range_max]*dim)
    
# # # # #     # 计算每个向量的范数
# # # # #     norms = np.linalg.norm(sample_scaled, axis=1)
    
# # # # #     # 找出非零向量（范数大于epsilon的向量）
# # # # #     non_zero_vectors = norms > epsilon
    
# # # # #     # 如果非零向量不够，可能需要生成更多样本
# # # # #     if np.sum(non_zero_vectors) < size:
# # # # #         return sobol_sequence(size, dim, range_min, range_max, epsilon)
    
# # # # #     # 只保留非零向量，并取前size个
# # # # #     result = sample_scaled[non_zero_vectors][:size]
    
# # # # #     return result

# # # # # def uniform_sphere(n_points, n_dim, radius=1):
# # # # #     # 从标准正态分布生成点
# # # # #     points = np.random.uniform(-1, 1, (n_points, n_dim))
    
# # # # #     # 将点归一化到单位球面上
# # # # #     norms = np.linalg.norm(points, axis=1, keepdims=True)
# # # # #     # 采用曼哈顿距离计算 norm
# # # # #     # norms = np.sum(np.abs(points), axis=1, keepdims=True)
# # # # #     points = points / norms

# # # # #     # 生成均匀分布的半径，范围从-1到1
# # # # #     radii = np.random.uniform(-1, 1, n_points) #**(1.0/n_dim)
    
# # # # #     # 将点缩放到对应半径
# # # # #     points = points * radii[:, np.newaxis] * radius
    
# # # # #     return points

# # # # # def sequential_importance_sampling(n_points, n_dim, sigma=0.1):
# # # # #     points = [np.random.uniform(-1, 1, n_dim)]
# # # # #     for k in range(1, n_points):
# # # # #         # 打印进度
# # # # #         # print(f"Generated {total_generated}/{num_points} points", end='\r')
# # # # #         print(f"Generated {k}/{n_points} points", end='\r')
# # # # #         while True:
# # # # #             new_point = np.random.uniform(-1, 1, n_dim)
# # # # #             if all(np.linalg.norm(new_point - p) > sigma for p in points):
# # # # #                 points.append(new_point)
# # # # #                 break
# # # # #     return np.array(points)

# # # # # def plot_distance_histogram(samples, dimensions):
# # # # #     distances = np.linalg.norm(samples, axis=1)
    
# # # # #     plt.figure(figsize=(10, 6))
# # # # #     plt.hist(distances, bins=50, density=True)
# # # # #     plt.title(f'Distance Distribution in {dimensions}-D Uniform Space')
# # # # #     plt.xlabel('Distance from Origin')
# # # # #     plt.ylabel('Density')
# # # # #     plt.show()

# # # # # # 使用示例
# # # # # sample_num = 10000
# # # # # sample_dim = 256
# # # # # points = sobol_sequence(sample_num, sample_dim)
# # # # # points_uniform = np.random.uniform(-1, 1, (sample_num, sample_dim))
# # # # # # points_uniform = uniform_sphere(sample_num, sample_dim)
# # # # # # points_uniform = sequential_importance_sampling(sample_num, sample_dim)

# # # # # print(points)

# # # # # # plot_distance_histogram(points, sample_dim)
# # # # # plot_distance_histogram(points_uniform, sample_dim)

# # # # # # # 对 points 进行PCA
# # # # # # from sklearn.decomposition import PCA
# # # # # # pca = PCA()
# # # # # # pca.fit(points)
# # # # # # points_pca = pca.transform(points)

# # # # # # pca1 = PCA()
# # # # # # pca1.fit(points_uniform)
# # # # # # points_pca1 = pca1.transform(points_uniform)

# # # # # # # 将 pca1、pca2 的累计方差贡献率绘制到同一个图中
# # # # # # plt.plot(np.cumsum(pca.explained_variance_ratio_), label="Sobol")
# # # # # # plt.plot(np.cumsum(pca1.explained_variance_ratio_), label="Uniform")
# # # # # # plt.xlabel("Number of components")
# # # # # # plt.ylabel("Cumulative explained variance")
# # # # # # plt.legend()
# # # # # # plt.show()

# # # # # # # 将 points_pca 和 points_pca1 的前两个主成分，绘制成两个散点图，放到同一个窗口中
# # # # # # fig, ax = plt.subplots(1, 2, figsize=(12, 6))
# # # # # # ax[0].scatter(points_pca[:, 0], points_pca[:, 1], s=1)
# # # # # # ax[0].set_title("Sobol")
# # # # # # ax[1].scatter(points_pca1[:, 0], points_pca1[:, 1], s=1)
# # # # # # ax[1].set_title("Uniform")
# # # # # # plt.show()


# # # # def sobol_sequence(size, dim, range_min=-1, range_max=1, epsilon=1e-6):
# # # #     # 创建Sobol采样器
# # # #     sampler = qmc.Sobol(d=dim, scramble=True)
    
# # # #     # 生成比需要的多一些的样本点，以便替换接近零的向量
# # # #     extra_samples = int(size * 0.1)  # 额外10%的样本
# # # #     total_samples = size + extra_samples
    
# # # #     # 生成[0, 1)范围内的样本
# # # #     sample = sampler.random(n=total_samples)
    
# # # #     # 将样本从[0, 1)映射到[range_min, range_max]
# # # #     sample_scaled = qmc.scale(sample, l_bounds=[range_min]*dim, u_bounds=[range_max]*dim)
    
# # # #     # 计算每个向量的范数
# # # #     norms = np.linalg.norm(sample_scaled, axis=1)
    
# # # #     # 找出非零向量（范数大于epsilon的向量）
# # # #     non_zero_vectors = norms > epsilon
    
# # # #     # 如果非零向量不够，可能需要生成更多样本
# # # #     if np.sum(non_zero_vectors) < size:
# # # #         return sobol_sequence(size, dim, range_min, range_max, epsilon)
    
# # # #     # 只保留非零向量，并取前size个
# # # #     result = sample_scaled[non_zero_vectors][:size]
    
# # # #     return result

# # # # def generate_uniform_samples(n_samples, dimensions, low=-1, high=1):
# # # #     return np.random.uniform(low, high, (n_samples, dimensions))
# # # #     # return sobol_sequence(n_samples, dimensions, low, high)

# # # # def generate_sliding_box(dimensions, x_position, box_size=0.3):
# # # #     min_coord = np.zeros(dimensions)
# # # #     max_coord = np.zeros(dimensions)
    
# # # #     min_coord[0] = x_position
# # # #     max_coord[0] = x_position + box_size
    
# # # #     # 其他维度的范围是 [-box_size/2, box_size/2]
# # # #     min_coord[1:] = -box_size / 2
# # # #     max_coord[1:] = box_size / 2
    
# # # #     return min_coord, max_coord

# # # # def count_points_in_box(points, min_coord, max_coord):
# # # #     in_box = np.all((points >= min_coord) & (points <= max_coord), axis=1)
# # # #     return np.sum(in_box)

# # # # # 设置参数
# # # # dimensions = 10
# # # # n_samples = 100000
# # # # n_positions = 1000  # x轴上的位置数量
# # # # box_size = 0.6
# # # # n_rounds = 20

# # # # # 准备x轴位置
# # # # x_positions = np.linspace(-1, 1 - box_size, n_positions)

# # # # # 进行多轮统计
# # # # all_counts = []

# # # # for round in range(n_rounds):
# # # #     print(f"Round {round + 1}/{n_rounds}")
    
# # # #     # 生成样本点
# # # #     points = generate_uniform_samples(n_samples, dimensions)
    
# # # #     # 沿x轴滑动盒子并统计
# # # #     counts = []
# # # #     for i, x_pos in enumerate(x_positions):
# # # #         if (i + 1) % 50 == 0:
# # # #             print(f"  Processed {i + 1}/{n_positions} positions")
        
# # # #         min_coord, max_coord = generate_sliding_box(dimensions, x_pos, box_size)
# # # #         count = count_points_in_box(points, min_coord, max_coord)
# # # #         counts.append(count)
    
# # # #     all_counts.append(counts)

# # # # # 转换为numpy数组以便于计算
# # # # all_counts = np.array(all_counts)

# # # # # 计算统计数据
# # # # mean_counts = np.mean(all_counts, axis=0)
# # # # std_counts = np.std(all_counts, axis=0)

# # # # # 绘制结果
# # # # plt.figure(figsize=(15, 10))

# # # # # 绘制每一轮的曲线
# # # # for i in range(n_rounds):
# # # #     plt.plot(x_positions, all_counts[i], alpha=0.3, label=f'Round {i+1}' if i == 0 else "")

# # # # # 绘制平均值曲线
# # # # plt.plot(x_positions, mean_counts, color='red', linewidth=2, label='Mean')

# # # # # 绘制标准差范围
# # # # plt.fill_between(x_positions, mean_counts - std_counts, mean_counts + std_counts, 
# # # #                  color='red', alpha=0.2, label='±1 Std Dev')

# # # # plt.title(f'Number of Points in Box vs. X-axis Position\n(128D, {n_samples} points, {n_rounds} rounds)')
# # # # plt.xlabel('X-axis Position of Box')
# # # # plt.ylabel('Number of Points in Box')
# # # # plt.legend()
# # # # plt.grid(True, alpha=0.3)

# # # # # 显示一些统计信息
# # # # overall_mean = np.mean(all_counts)
# # # # overall_std = np.std(all_counts)
# # # # plt.text(0.02, 0.98, f'Overall Mean: {overall_mean:.2f}\nOverall Std Dev: {overall_std:.2f}', 
# # # #          transform=plt.gca().transAxes, verticalalignment='top')

# # # # plt.show()

# # # # # 计算理论上的点数
# # # # box_volume = box_size ** dimensions
# # # # total_volume = 2 ** dimensions
# # # # expected_points = n_samples * (box_volume / total_volume)
# # # # print(f"\nTheoretical expected number of points in box: {expected_points:.2e}")



# # # import numpy as np

# # # arr1 = np.array([[1,1],[2,2],[3,3],[4,4]])
# # # print(arr1.shape)

# # # arr_mean = np.sum(np.mean(np.abs(arr1), axis=0))
# # # print(arr_mean)


# # # # def adjust_vector_projection_orthonormal(A, X, desired_projections):
# # # #     """
# # # #     调整向量 A，使其在正交基 X 上的投影等于 desired_projections。

# # # #     参数：
# # # #     A: numpy.ndarray，形状为 (128,)
# # # #     X: numpy.ndarray，形状为 (4, 128)，线性无关的基向量 X0, X1, X2, X3
# # # #     desired_projections: numpy.ndarray，形状为 (4,)，目标投影值 y0, y1, y2, y3

# # # #     返回：
# # # #     A_prime: numpy.ndarray，形状为 (128,)，调整后的向量
# # # #     """
# # # #     # 使用 QR 分解将 X 正交化
# # # #     Q, R = np.linalg.qr(X.T)
# # # #     # Q 的形状为 (128, 4)，正交列向量
# # # #     U = Q[:, :4].T  # 形状转换为 (4, 128)

# # # #     # 计算 A 在正交基上的当前投影
# # # #     current_projections = U @ A  # 形状为 (4,)

# # # #     # print(current_projections)

# # # #     # 计算需要调整的投影差值
# # # #     delta = desired_projections - current_projections  # 形状为 (4,)

# # # #     # 调整向量 A
# # # #     A_prime = A + U.T @ delta  # U.T 形状为 (128,4), delta 是 (4,)

# # # #     return A_prime

# # # # # 示例用法
# # # # if __name__ == "__main__":
# # # #     np.random.seed(42)  # 为了结果可重复

# # # #     # 随机生成向量 A
# # # #     A = np.random.rand(128)

# # # #     # 随机生成 4 个线性无关的基向量 X0-3
# # # #     while True:
# # # #         X = np.random.rand(4, 128)
# # # #         if np.linalg.matrix_rank(X) == 4:
# # # #             break
# # # #     print("基向量 X0-3 已生成并且线性无关。")

# # # #     # 定义期望的投影值 y0-3
# # # #     desired_projections = np.array([-4.70228886,-1.53184301, 1.37705629,-0.01513064])

# # # #     # 计算调整后的向量 A'
# # # #     A_prime = adjust_vector_projection_orthonormal(A, X, desired_projections)

# # # #     print(A)
# # # #     print(A_prime)

# # # #     # 验证结果
# # # #     # 正交化 X 以获得 U
# # # #     Q, R = np.linalg.qr(X.T)
# # # #     U = Q[:, :4].T  # (4,128)

# # # #     actual_projections = U @ A_prime
# # # #     print("期望的投影值:", desired_projections)
# # # #     print("实际的投影值:", actual_projections)

# # # #     # 检查误差
# # # #     if np.allclose(actual_projections, desired_projections, atol=1e-10):
# # # #         print("调整成功，A' 的投影已满足要求。")
# # # #     else:
# # # #         print("调整失败，存在误差。")


# # import numpy as np
# # from bokeh.plotting import figure, show, output_file
# # from bokeh.models import ColumnDataSource, HoverTool
# # from bokeh.palettes import Category20

# # # 指定输出的 HTML 文件
# # output_file("interactive_histograms.html")

# # # 生成示例数据
# # num_curves = 20
# # num_bins = 50

# # # 原始 x 值（0 到 49）
# # x = np.arange(num_bins)

# # # 自定义的 x 轴标签范围（例如 0 到 1000）
# # custom_x_labels = np.linspace(0, 1000, num_bins)

# # data = np.random.randint(0, 100, size=(num_curves, num_bins))
# # names = [f'曲线 {i+1}' for i in range(num_curves)]
# # colors = Category20[20]  # 获取20种不同的颜色

# # # 准备数据源
# # source = ColumnDataSource(data=dict(
# #     xs = [custom_x_labels.tolist()] * num_curves,   # x坐标列表，每条曲线对应自定义的 x 数组
# #     ys = data.tolist(),                              # y坐标列表，每条曲线对应一个 y 数组
# #     names = names,                                   # 曲线名称列表
# #     line_color=colors                                # 曲线颜色列表
# # ))

# # # 创建绘图对象，设置图表宽度填满页面宽度
# # p = figure(title="交互式直方图曲线",
# #            tools="pan,wheel_zoom,box_zoom,reset,save",
# #            sizing_mode="stretch_width",  # 使图表宽度填满页面
# #            height=600)                   # 可根据需要调整高度

# # # 绘制多条曲线
# # renderer = p.multi_line(xs='xs', ys='ys', line_color='line_color', source=source, line_width=2, alpha=0.6,
# #                         hover_line_color='red',    # 高亮时的线条颜色设为红色
# #                         hover_line_alpha=1.0, hover_line_width=4)

# # # 添加Hover工具
# # hover = HoverTool(
# #     tooltips=[('曲线名称', '@names')],
# #     renderers=[renderer],
# #     line_policy='nearest',
# #     show_arrow=False,
# #     mode='mouse'
# # )
# # p.add_tools(hover)

# # # 设置 x 轴范围为自定义范围
# # p.x_range.start = custom_x_labels[0]
# # p.x_range.end = custom_x_labels[-1]

# # # 显示绘图
# # show(p)

# # import math

# # def compute_P0(P1):
# #     if P1 < 0 or P1 > 1:
# #         raise ValueError("P1 必须在 0 和 1 之间。")
# #     if P1 == 1:
# #         return 1.0
# #     elif P1 == 0:
# #         return 0.0
# #     else:
# #         exponent = 1.0 / 64.0
# #         ln_base = math.log(1.0 - P1)
# #         ln_root = exponent * ln_base
# #         root = math.exp(ln_root)
# #         P0 = 1.0 - root
# #         return P0

# # if __name__ == "__main__":
# #     # 输入 P1
# #     P1 = float(input("请输入 batch 成功率 P1（介于 0 和 1 之间）："))
# #     P0 = compute_P0(P1)
# #     print(f"单次成功率 P0 为：{P0}")

# # from math import comb
# # from scipy.stats import dirichlet
# # import numpy as np

# # def binomial_cdf(n, k, p) -> int:
# #     """计算二项分布的累积分布函数"""
# #     # P(X≤k) = P(X=0) + ... + P(X=k)
# #     return sum(comb(n, i) * (p ** i) * ((1 - p) ** (n - i)) for i in range(k + 1))

# # def prob_n_at_least_k(n, k, p) -> int:
# #     """计算在n次实验中至少发生k次的概率"""
# #     return 1 - binomial_cdf(n, k - 1, p)

# # def calculate_average_prob(n, alpha, sample_size):
# #     p_values = dirichlet.rvs(alpha, size=sample_size)
# #     avg_prob = np.mean(p_values[:, 0])
# #     avg_prob_1_in_64 = np.mean(prob_n_at_least_k(n, 1, p_values[:, 0]))
# #     avg_prob_3_in_64 = np.mean(prob_n_at_least_k(n, 3, p_values[:, 0]))
# #     return avg_prob, avg_prob_1_in_64, avg_prob_3_in_64

# # # 参数值
# # n = 64
# # p = 0.075
# # alpha = [p, 1 - p]
# # sample_size = 2 ** 18

# # # 计算平均概率
# # avg_prob, avg_prob_1_in_64, avg_prob_3_in_64 = calculate_average_prob(n, alpha, sample_size)

# # print(f"平均概率: {avg_prob}")
# # print(f"64次平均至少发生1次的概率: {avg_prob_1_in_64}")
# # print(f"64次平均至少发生3次的概率: {avg_prob_3_in_64}")

# # import matplotlib.pyplot as plt

# # # Data
# # models = ['Solution-Only', 'Dualformer', 'Sapient-H']
# # values_1in64 = [30.0, 96.6, 100.0]
# # values_1in1 = [17.9, 52.2, 97.3]

# # # Update model names to include line breaks
# # models_with_line_breaks = [name.replace(' ', '\n') for name in models]

# # # Define colors
# # gray = '#333333'  # RGB(51,51,51)
# # blue = '#60A5FA'  # RGB(96,165,250)

# # # Assign colors to each bar
# # colors_1in64 = [gray, gray, blue]  # Colors for '1 in 64' bars
# # colors_1in1 = [gray, gray, blue]   # Colors for '1 in 1' bars

# # # Bar configuration
# # bar_width = 0.8
# # group_gap = 2.0  # Gap between the two groups

# # # Positions of bars on x-axis
# # x1 = [0, 1, 2]  # Positions for '1 in 64' bars
# # x2 = [x + group_gap + max(x1) for x in x1]  # Positions for '1 in 1' bars

# # # Create figure and axis
# # fig, ax = plt.subplots(figsize=(10, 6))

# # # Plotting the bars for '1 in 64' with specified colors
# # bars1 = ax.bar(x1, values_1in64, width=bar_width, color=colors_1in64)

# # # Plotting the bars for '1 in 1' with specified colors
# # bars2 = ax.bar(x2, values_1in1, width=bar_width, color=colors_1in1)

# # # Set x-axis ticks and labels with two-line model names
# # xticks_positions = x1 + x2
# # xticks_labels = models_with_line_breaks + models_with_line_breaks

# # ax.set_xticks(xticks_positions)
# # ax.set_xticklabels(xticks_labels)

# # # Adjust the x-axis tick labels
# # for tick in ax.get_xticklabels():
# #     tick.set_verticalalignment('top')
# #     tick.set_horizontalalignment('center')

# # # Add grouping labels above the bars
# # # Compute maximum bar height
# # max_height = max(max(values_1in64), max(values_1in1))

# # # Set y-axis limit to accommodate the labels
# # y_max = max_height + 20
# # ax.set_ylim(0, y_max)

# # # Positions for group labels
# # group_label_y = max_height + 10  # Position above the tallest bar

# # ax.text(sum(x1)/len(x1), group_label_y, '1 in 64', ha='center', va='bottom', fontsize=14, fontweight='bold')
# # ax.text(sum(x2)/len(x2), group_label_y, '1 in 1', ha='center', va='bottom', fontsize=14, fontweight='bold')

# # # Set y-axis label and title
# # ax.set_ylabel('Success Rate (%)')
# # ax.set_title('Success Rates in Maze-30x30 Navigation Task')

# # # Function to add labels above each bar
# # def autolabel(rects):
# #     """Attach a text label above each bar displaying its height"""
# #     for rect in rects:
# #         height = rect.get_height()
# #         ax.annotate(f'{height:.1f}%',
# #                     xy=(rect.get_x() + rect.get_width() / 2, height),
# #                     xytext=(0, 3),  # Vertical offset
# #                     textcoords="offset points",
# #                     ha='center', va='bottom')

# # # Add labels above the bars
# # autolabel(bars1)
# # autolabel(bars2)

# # # Customize the plot look
# # ax.spines['top'].set_visible(False)
# # ax.spines['right'].set_visible(False)
# # ax.set_xlim(-0.5, max(x2) + 1)

# # # Adjust layout to prevent clipping of tick-labels
# # plt.tight_layout()

# # # Display the plot
# # plt.show()

# import pandas as pd
# import matplotlib.pyplot as plt
# import seaborn as sns

# # 读取数据文件
# df1 = pd.read_csv('/home/t/Downloads/wandb_export_2024-11-16T11_33_19.783-08_00.csv')
# df2 = pd.read_csv('/home/t/Downloads/wandb_export_2024-11-16T11_33_26.818-08_00.csv')
# df3 = pd.read_csv('/home/t/Downloads/wandb_export_2024-11-16T11_33_48.039-08_00.csv')

# # 设置图表样式
# plt.style.use('seaborn')
# plt.figure(figsize=(12, 6))

# # 绘制每个模型的曲线
# models = [
#     ('SuperLlama Deep', 'black'),
#     ('SuperLlama DeepAndWide', 'black'),
#     ('SuperLlama Wide', 'black'),
#     ('Llama baseline', 'black'),
#     ('Sapient H', '#1f77b4')  # 蓝色
# ]

# for model_name, color in models:
#     # 获取模型相关的列
#     columns = [col for col in df1.columns if model_name in col]
#     if len(columns) >= 3:
#         main_col = [col for col in columns if not col.endswith('MIN') and not col.endswith('MAX')][0]
#         min_col = [col for col in columns if col.endswith('MIN')][0]
#         max_col = [col for col in columns if col.endswith('MAX')][0]
        
#         # 绘制主线
#         plt.plot(df1['Step'], df1[main_col], color=color, label=model_name)
        
#         # 绘制置信区间
#         plt.fill_between(df1['Step'], 
#                         df1[min_col],
#                         df1[max_col],
#                         color=color,
#                         alpha=0.2)

# # 设置图表属性
# plt.xlabel('Step')
# plt.ylabel('Accuracy')
# plt.title('test/all')
# plt.grid(True, linestyle='--', alpha=0.7)
# plt.legend()

# # 设置坐标轴范围
# plt.xlim(0, 35000)
# plt.ylim(0, 1.0)

# # 保存图表
# plt.savefig('model_comparison.png', dpi=300, bbox_inches='tight')
# plt.show()

import matplotlib.pyplot as plt
import numpy as np

# Data
steps = ['1u', '2u', '4u', '8u']
accuracies_18M = [55.42, 67.666, 77.39, 77.792]
accuracies_57M = [None, None, 82.57, 85.21]  # None for missing data
baseline_accuracy = 63.339

# Create figure
plt.figure(figsize=(8, 5))

# Set bar properties
bar_width = 0.35
group_gap = 0.8
index = np.arange(len(steps)) * group_gap

# Create bars
for i in range(len(steps)):
    if accuracies_18M[i] is not None:
        plt.bar(index[i], accuracies_18M[i], bar_width, 
                color='#2ecc71', label='Sapient-H 18M' if i == 0 else "")
    if accuracies_57M[i] is not None:
        plt.bar(index[i] + bar_width, accuracies_57M[i], bar_width,
                color='#3498db', label='Sapient-H 57M' if i == 2 else "")

# Adding the baseline
plt.axhline(y=baseline_accuracy, color='#e74c3c', linestyle='--', 
            label='Llama/TFM++ 27M@3ep')

# Customize the plot
plt.xlabel('Recurrent Steps')
plt.ylabel('Accuracy (%)')
plt.title('DeepMind Mathematics Dataset')
plt.xticks(index + bar_width/2, steps)
plt.ylim(30, 100)
plt.legend()

# Adjust layout
plt.tight_layout()

# Save the plot
plt.savefig("draw.png", dpi=300, bbox_inches='tight')